﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Linq;
using System.Net;
using System.ServiceModel.DomainServices.Client;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Shapes;
using AppLab.Controls;
using AppLab.Web;
using AppLab.Web.Services;
using AppLab.Data.Models;

namespace AppLab.Views
{
    public partial class Submit : Page
    {
        private IList<OperationBase> possiblyPendingOperations = new List<OperationBase>();
        private SubmitData submitData = new SubmitData();
        private FlowContext flow = new FlowContext();
        private ComboBox comboBoxWithMobiles = new ComboBox();

        public Submit()
        {
            InitializeComponent();
            PageScrollViewer.SetIsMouseWheelScrollingEnabled(true);
            this.Title = ApplicationStrings.SubmitPageTitle;
            this.DataContext = this.submitData;
        }

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {

        }

        // Executes when the user tries to leave this page.
        protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
        {
            foreach (OperationBase operation in this.possiblyPendingOperations)
            {
                if (!operation.IsComplete)
                {
                    if (operation.CanCancel)
                    {
                        operation.Cancel();
                    }
                    else
                    {
                        e.Cancel = true;
                    }
                }
            }
        }

        private void SubmitForm_AutoGeneratingField(object dataForm, DataFormAutoGeneratingFieldEventArgs e)
        {

            // Put all the fields in adding mode
            e.Field.Mode = DataFieldMode.AddNew;

            if (e.PropertyName == "PackageName")
            {
                UploadPackageTextBox upload = new UploadPackageTextBox(submitData);
                e.Field.ReplaceTextBox(upload, UploadPackageTextBox.TextProperty, null);
                upload.KeyDown += new KeyEventHandler(upload_KeyDown);
                upload.TextChanged += new TextChangedEventHandler(upload_TextChanged);
            }
            else if (e.PropertyName == "UpGradePackageName")
            {
                UploadUpgradePackageTextBox upload = new UploadUpgradePackageTextBox(submitData);
                e.Field.ReplaceTextBox(upload, UploadUpgradePackageTextBox.TextProperty, null);
                upload.KeyDown += new KeyEventHandler(upload_KeyDown);
                //upload.TextChanged += new TextChangedEventHandler(upload_TextChanged);
            }
            else if (e.PropertyName == "SubmitComment")
            {
                TextBox textBox = (TextBox)e.Field.Content;
                textBox.Height = 80;
                textBox.MaxLength = 100;
                textBox.TextWrapping = TextWrapping.Wrap;
                textBox.AcceptsReturn = true;
                textBox.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
            }
            else if (e.PropertyName == "Brand")
            {
                // Create a ComboBox populated with security questions
                ComboBox comboBoxWithBrands = this.CreateComboBoxWithBrands();
                comboBoxWithBrands.SelectionChanged += new SelectionChangedEventHandler(ComboBoxWithBrands_SelectionChanged);
                // Replace the control
                // Note: Since TextBox.Text treats empty text as string.Empty and ComboBox.SelectedItem
                // treats an empty selection as null, we need to use a converter on the binding
                e.Field.ReplaceTextBox(comboBoxWithBrands, ComboBox.SelectedItemProperty, binding => binding.Converter = new BrandValueConverter());
            }
            else if (e.PropertyName == "Mobile")
            {
                comboBoxWithMobiles.SelectedItem = null;
                // Replace the control
                // Note: Since TextBox.Text treats empty text as string.Empty and ComboBox.SelectedItem
                // treats an empty selection as null, we need to use a converter on the binding
                e.Field.ReplaceTextBox(comboBoxWithMobiles, ComboBox.SelectedItemProperty, binding => binding.Converter = new MobileTypeValueConverter());
            }
            else if (e.PropertyName == "SubmitType")
            {
                ComboBox comboBoxWithSubmitType = this.CreateComboBoxWithSubmitType();
                e.Field.ReplaceTextBox(comboBoxWithSubmitType, ComboBox.SelectedItemProperty, binding => binding.Converter = new SubmitTypeConverter());
            }
            else if (e.PropertyName == "ReleaseName")
            {
                UploadReleaseNoteTextBox upload = new UploadReleaseNoteTextBox(submitData);
                e.Field.ReplaceTextBox(upload, UploadReleaseNoteTextBox.TextProperty, null);
                upload.KeyDown += new KeyEventHandler(upload_KeyDown);
                //upload.TextChanged += new TextChangedEventHandler(upload_TextChanged);
            }
            else if (e.PropertyName == "InsideCompatiableTestReportName")
            {
                UploadInsideCompatiableTestReportTextBox upload = new UploadInsideCompatiableTestReportTextBox(submitData);
                e.Field.ReplaceTextBox(upload, UploadInsideCompatiableTestReportTextBox.TextProperty, null);
                upload.KeyDown += new KeyEventHandler(upload_KeyDown);
                //upload.TextChanged += new TextChangedEventHandler(upload_TextChanged);
            }
            else if (e.PropertyName == "AnythingElseName")
            {
                UploadAnytingElseTextBox upload = new UploadAnytingElseTextBox(submitData);
                e.Field.ReplaceTextBox(upload, UploadAnytingElseTextBox.TextProperty, null);
                upload.KeyDown += new KeyEventHandler(upload_KeyDown);
                //upload.TextChanged += new TextChangedEventHandler(upload_TextChanged);
            }
            else if (e.PropertyName == "MediaClientVersion")
            {
                TextBox textBox = (TextBox)e.Field.Content;
                textBox.MaxLength = 100;
            }
        }

        void upload_TextChanged(object sender, TextChangedEventArgs e)
        {
            (sender as TextBox).IsReadOnly = true;
        }

        void upload_KeyDown(object sender, KeyEventArgs e)
        {
            e.Handled = true;
        }

        private void ComboBoxWithBrands_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            comboBoxWithMobiles.SelectionChanged -= ComboBoxWithMobiles_SelectionChanged;
            if (submitData.Brand > 0)
            {
                // Use reflection to grab all the localized security questions
                var query = flow.GetMobileTypesQuery(submitData.Brand);
                var loadOp = flow.Load(query);
                // Binding the ComboBox object
                comboBoxWithMobiles.ItemsSource = loadOp.Entities;
                comboBoxWithMobiles.DisplayMemberPath = "TypeName";
            }
            else
            {
                comboBoxWithMobiles.ItemsSource = null;
            }
            comboBoxWithMobiles.SelectionChanged += ComboBoxWithMobiles_SelectionChanged;
        }

        private void ComboBoxWithMobiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            flow.GetMediaClient2(submitData.Mobile, op =>
            {
                if (!op.HasError)
                    submitData.MediaClientVersionPattern = (op.Value == null) ? string.Empty : op.Value.MediaClientVersion;
            }, null);

            //flow.GetOS2(submitData.Mobile, op =>
            //{
            //    if (!op.HasError)
            //        submitData.PackageOSPattern = (op.Value == null) ? string.Empty : op.Value.OSName.Replace(".", "");
            //}, null);
        }

        private ComboBox CreateComboBoxWithBrands()
        {
            // Use reflection to grab all the localized security questions
            var query = flow.GetBrandsQuery();
            var loadOp = flow.Load(query);

            // Create and initialize the ComboBox object
            ComboBox comboBox = new ComboBox();
            comboBox.ItemsSource = loadOp.Entities;
            comboBox.DisplayMemberPath = "BrandName";
            return comboBox;
        }

        private ComboBox CreateComboBoxWithSubmitType()
        {
            var query = flow.GetSubmitTypesQuery();
            var loadOp = flow.Load(query);

            ComboBox comboBox = new ComboBox();
            comboBox.ItemsSource = loadOp.Entities;
            comboBox.DisplayMemberPath = "SubmitTypeName";
            return comboBox;
        }

        private void OK_Click(object sender, RoutedEventArgs e)
        {
            // We need to force validation since we are not using the standard OK
            // button from the DataForm.  Without ensuring the form is valid, we
            // would get an exception invoking the operation if the entity is invalid.
            if (this.submitForm.ValidateItem())
            {
                if (AdvanceValidateItem())
                {
                    this.submitData.CurrentOperation = this.flow.Submit(
                        this.submitData,
                        this.SubmitOperation_Completed, null);

                    this.possiblyPendingOperations.Add(this.submitData.CurrentOperation);
                }
            }
        }

        // Validate package name
        private bool AdvanceValidateItem()
        {
            if (WebContext.Current.User.IsAuthenticated)
            {
                submitData.SubmitBy = WebContext.Current.User.Name;
                submitData.SubmitDisplayName = WebContext.Current.User.DisplayName;
            }
            else
            {
                MessageBox.Show("您必须先登录", this.Title, MessageBoxButton.OK);
                return false;
            }


            //if (String.IsNullOrWhiteSpace(submitData.PackageName))
            //{
            //    this.submitData.ValidationErrors.Add(new ValidationResult(
            //        String.Format(ErrorResources.SubmitPackageInvalidName, "TYSX_版本号(D.D.D.D)-操作系统-型号.* 如:TYSX_1.0.0.1-WM6-LG-KV7551"), new string[] { "PackageName" }));
            //    return false;
            //}
            //string strTypeName = (comboBoxWithMobiles.SelectedValue as MobileType).TypeName;
            ////验证安装包的版本是否符合标准
            //string _getValidPackageNameRegX = GetValidPackageNameRegX(this.submitData.PackageNamePattern, this.submitData.SubmitType);
            //string _validPackageName = _getValidPackageNameRegX + strTypeName;

            //string _validUpGradePackageName = GetValidUpgradePackageNameRegX(_getValidPackageNameRegX) + strTypeName;
            //if (!Regex.IsMatch(submitData.PackageName, _validPackageName + ".[a-zA-Z]+", RegexOptions.None))
            //{
            //    this.submitData.ValidationErrors.Add(new ValidationResult(
            //        String.Format(ErrorResources.SubmitPackageInvalidName, _validPackageName + ".*"), new string[] { "PackageName" }));
            //    return false;
            //}
            //else if (!Regex.IsMatch(submitData.UpGradePackageName, _validUpGradePackageName + ".[a-zA-Z]+", RegexOptions.None))
            //{
            //    this.submitData.ValidationErrors.Add(new ValidationResult(
            //        String.Format(ErrorResources.SubmitPackageInvalidName, _validUpGradePackageName + ".*"), new string[] { "UpGradePackageName" }));
            //    return false;
            //}
            //else if (submitData.PackageContent == null)
            //{
            //    this.submitData.ValidationErrors.Add(new ValidationResult(
            //        ErrorResources.SubmitPackageNameChanged, new string[] { "PackageName" }));
            //    return false;
            //}
            //else
            //{
            //    return true;
            //}

            if (!Regex.IsMatch(submitData.MediaClientVersion, @"\d{1,5}.\d{1,5}.\d{1,5}.\d{1,5}", RegexOptions.None))
            {
                this.submitData.ValidationErrors.Add(new ValidationResult(
                    String.Format(ErrorResources.SubmitPackageInvalidName, "版本格式错误!"), new string[] { "MediaClientVersion" }));
                return false;
            }

            //if (submitData.MediaClientVersion.)
            //{
            //    System.Windows.
            //}



            return true;
        }

        private void SubmitOperation_Completed(InvokeOperation<Guid> operation)
        {
            if (!operation.IsCanceled)
            {
                if (operation.HasError)
                {
                    ErrorWindow.CreateNew(operation.Error);
                    operation.MarkErrorAsHandled();
                }
                else if (operation.Value != Guid.Empty)
                {
                    MessageBox.Show(PopupDialogStrings.SuccessfullySubmittedPackage, this.Title, MessageBoxButton.OK);
                    this.NavigationService.Refresh();
                }
                else
                {
                    ErrorWindow.CreateNew(ErrorResources.ErrorWindowGenericError);
                }
            }
        }

        public string GetValidUpgradePackageNameRegX(string NewestPackageName)
        {
            string[] temp = NewestPackageName.Split('.', '-', '_');
            temp[4] = (Convert.ToInt16(temp[4]) + 1).ToString();
            temp[5] = submitData.PackageOSPattern;
            return temp[0] + "_" + temp[1] + "." + temp[2] + "." + temp[3] + "." + temp[4] + "-" + temp[5] + "-";
        }

        public string GetValidPackageNameRegX(string NewestPackageName, int submitType)
        {
            //flow.GetMediaClient2(

            //var query = flow.GetMediaClientQuery(TerminalID);
            //var loadOp = flow.Load(query);

            //while (true)
            //{
            //    Thread.Sleep(100);
            //    if (loadOp.IsComplete)
            //        break;
            //}
            //if (loadOp.Entities.Count() == 0)//如果没有相关的终端安装程序
            //{
            //    return @".*";
            //}
            //string LastPackage = flow.GetMediaClient2Sync(TerminalID).MediaClientName;
            if (!string.IsNullOrEmpty(NewestPackageName))
            {
                string[] temp = NewestPackageName.Split('.', '-', '_');
                try
                {
                    if (submitType == 1)//缺陷修复
                    {
                        temp[3] = (Convert.ToInt16(temp[3]) + 1).ToString();
                        temp[4] = "0";
                    }
                    else if (submitType == 2)//功能完善
                    {
                        temp[2] = (Convert.ToInt16(temp[2]) + 1).ToString();
                        temp[3] = "0";
                        temp[4] = "0";
                    }
                    else if (submitType == 3)//版本改进
                    {
                        temp[1] = (Convert.ToInt16(temp[1]) + 1).ToString();
                        temp[2] = "0";
                        temp[3] = "0";
                        temp[4] = "0";
                    }
                    else
                    {
                        temp[4] = (Convert.ToInt16(temp[4]) + 1).ToString();
                    }
                    return temp[0] + "_" + temp[1] + "." + temp[2] + "." + temp[3] + "." + temp[4] + "-" + temp[5] + "-";
                }
                catch
                {
                    return @"TYSX_\d{1,5}.\d{1,5}.\d{1,5}.\d{1,5}-[a-zA-Z\d]+-";
                }
            }
            else
            {
                //首次提交包是1.0.*.*开始的
                return @"TYSX_1.0.0.0-" + submitData.PackageOSPattern + "-";
            }
        }
    }
}